﻿using CaseManagerLibrary.Encrypt;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CaseManagerLibrary.Licence
{
    public static class LicenceManager
    {
        public static void CreateLicenceFile(LicenceInfo licence, string fileName)
        {
            try
            {
                var lic = new LicenceInfo();
                foreach (var prop in typeof(LicenceInfo).GetProperties())
                {
                    prop.SetValue(lic, prop.GetValue(licence), null);
                }
                string sn = lic.SN;

                lic.SN = EncryptKit.DESEncode(lic.SN, lic.Key);
                lic.StartTime = EncryptKit.DESEncode(lic.StartTime, lic.Key);
                lic.EndTime = EncryptKit.DESEncode(lic.EndTime, lic.Key);
                lic.Key = EncryptKit.DESEncode(lic.Key, sn);

                string json = JsonConvert.SerializeObject(lic);

                string str_lic = EncryptKit.DESEncode(json, sn);
                string str_md5 = EncryptKit.ToUpperMd5(str_lic);

                string str = str_md5 + str_lic;

                System.IO.File.WriteAllText(fileName, str);
            }
            catch (Exception ex)
            { }
        }

        private static string CheckMD5(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return "";
            }

            if (str.Length < 32)
            {
                return "";
            }

            string str_md5 = str.Substring(0, 32);

            string str_lic = str.Substring(32, str.Length - 32);

            string str_lic_md5 = EncryptKit.ToUpperMd5(str_lic);

            if (str_md5 == str_lic_md5)
            {
                return str_lic;
            }
            else
            {
                return "";
            }
        }

        public static LicenceInfo GetLicenceContent(string licenceStr, string sn)
        {
            LicenceInfo licence = null;

            try
            {
                string str = CheckMD5(licenceStr);

                if (!string.IsNullOrEmpty(str))
                {
                    string json = EncryptKit.DESDecode(str, sn);

                    licence = JsonConvert.DeserializeObject<LicenceInfo>(json);

                    licence.Key = EncryptKit.DESDecode(licence.Key, sn);

                    licence.SN = EncryptKit.DESDecode(licence.SN, licence.Key);

                    licence.StartTime = EncryptKit.DESDecode(licence.StartTime, licence.Key);

                    licence.EndTime = EncryptKit.DESDecode(licence.EndTime, licence.Key);
                }
            }
            catch (Exception ex)
            { }

            return licence;
        }

        public static LicenceInfo GetLicenceContentFromFile(string file, string sn)
        {
            string str = System.IO.File.ReadAllText(file);

            return GetLicenceContent(str, sn);
        }

        public static LicenceCheckCode Check(LicenceInfo licence, string sn, LicenceDaysFrom daysFrom)
        {
            try
            {
                if (licence == null)
                {
                    return LicenceCheckCode.InvalidLicenceFile;
                }

                DateTime startTime;
                DateTime endTime;

                if (licence.SN != sn)
                {
                    return LicenceCheckCode.InvalidSN;
                }

                if (!DateTime.TryParse(licence.StartTime, out startTime))
                {
                    return LicenceCheckCode.InvalidStartTime;
                }

                if (!DateTime.TryParse(licence.EndTime, out endTime))
                {
                    return LicenceCheckCode.InvalidEndTime;
                }

                if (daysFrom != LicenceDaysFrom.Ignore)
                {
                    int days = 0;

                    if (daysFrom == LicenceDaysFrom.SysTime)
                    {
                        days = Convert.ToInt32((DateTime.Now - startTime).TotalDays);
                    }
                    else if (daysFrom == LicenceDaysFrom.Custom)
                    {
                        days = GetDaysFromCustom();
                    }

                    if ((endTime - startTime).TotalDays < days)
                    {
                        return LicenceCheckCode.Expried;
                    }
                }

                return LicenceCheckCode.Success;
            }
            catch (Exception ex)
            {
                return LicenceCheckCode.Unknown;
            }
        }

        private static int GetDaysFromCustom()
        {
            int days = 0;
            return days;
        }
    }

    public enum LicenceCheckCode : int
    {
        Unknown = -1,
        Success = 0,
        InvalidStartTime = 1,
        InvalidEndTime = 2,
        Expried = 3,
        InvalidSN = 4,
        NoLicenceFile = 5,
        InvalidLicenceFile = 6,
    }

    public enum LicenceDaysFrom : int
    {
        Ignore = 0,
        SysTime = 1,
        Custom = 2,
    }
}
